package com.atguigu.gulimall.search.thread;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 两任务组合: 都要完成(原子性?)
 * thenCombine: 即接收结果,又有返回值
 * public <U,V> CompletableFuture<V> thenCombine(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn);
 * public <U,V> CompletableFuture<V> thenCombineAsync(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn);
 * public <U,V> CompletableFuture<V> thenCombineAsync(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn, Executor executor);
 *
 * thenAcceptBoth: 只接收结果,没有返回值
 * public <U> CompletableFuture<Void> thenAcceptBoth(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action);
 * public <U> CompletableFuture<Void> thenAcceptBothAsync(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action);
 * public <U> CompletableFuture<Void> thenAcceptBothAsync(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action, Executor executor);
 *
 * runAfterBoth: 不接收结果,也没有返回值
 * public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other, Runnable action);
 * public CompletableFuture<Void> runAfterBothAsync(CompletionStage<?> other, Runnable action);
 * public CompletableFuture<Void> runAfterBothAsync(CompletionStage<?> other, Runnable action, Executor executor);
 *
 * 两个任务必须都完成，触发该任务。
 * thenCombine:组合两个future，获取两个future的返回结果，并返回当前任务的返回值
 * thenAcceptBoth:组合两个future，获取两个future任务的返回结果，然后处理任务，没有
 * 返回值。
 * runAfterBoth:组合两个future，不需要获取future的结果，只需两个future处理完任务后，
 * 处理该任务。
 */
public class ThreadTest3 {
    public static ExecutorService excutor = Executors.newFixedThreadPool(10);

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("main start ....");
        CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(()->{
            System.out.println("任务1 start..");
            System.out.println("任务1 end..");
            return 1+1;
        });

        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(()->{
            System.out.println("任务2 start..");
            System.out.println("任务2 end..");
            return "hello";
        });

        /**
         * runAfterBothAsync 不能接受返回值
         */
        CompletableFuture<Void> future3 = future1.runAfterBothAsync(future2, () -> {
            System.out.println("任务3开始");
        }, excutor);


        /**
         * 任务4希望任务1和任务2都完成后执行
         */
        CompletableFuture<String> future4 = future1.thenCombineAsync(future2, (result1, result2) -> {
            return "任务4 ：组合前两个任务的返回值返回 --" + result1 + "---" + result2;
        }, excutor);
        System.out.println("main end.... 返回值：" + future4.get());
    }
}
